package za.org.jcicada.cfgmngr.impl;

import java.net.URI;
import java.util.List;

import za.org.jcicada.cfgmngr.IPhysicalClient;
import za.org.jcicada.cfgmngr.IPhysicalServer;
import za.org.jcicada.cfgmngr.messages.AttachReply;
import za.org.jcicada.cfgmngr.messages.AttachRequest;
import za.org.jcicada.cfgmngr.messages.DetachReply;
import za.org.jcicada.cfgmngr.messages.DetachRequest;
import za.org.jcicada.cfgmngr.messages.GetChildrenReply;
import za.org.jcicada.cfgmngr.messages.GetChildrenRequest;
import za.org.jcicada.cfgmngr.messages.NodeSystemsReply;
import za.org.jcicada.cfgmngr.messages.NodeSystemsRequest;
import za.org.jcicada.cfgmngr.messages.ViewEventInform;
import za.org.jcicada.cfgmngr.messages.ViewSensorInform;
import za.org.jcicada.cfgmngr.messages.ViewSensorsReply;
import za.org.jcicada.cfgmngr.messages.ViewSensorsRequest;
import za.org.jcicada.comms.IConnector;
import za.org.jcicada.comms.impl.MessageListenerBase;
import za.org.jcicada.comms.impl.ProxyBase;
import za.org.jcicada.genss.PhysicalURN;

/**
 * IPhysicalServer implementation that proxies requests through to a
 * remote physical server.
 * 
 * @author rcrida
 */
public class PhysicalServerProxy extends ProxyBase<IPhysicalClient> implements IPhysicalServer {

	public PhysicalServerProxy(IConnector connector) {
		super(connector);
	}
	
	public PhysicalServerProxy(URI locationURI) {
		super(locationURI);
	}
	
	@Override
	protected MessageListenerBase createReceiver(IPhysicalClient client) {
		return new Receiver(client);
	}
	
	public void requestGetChildren(IPhysicalClient client, PhysicalURN parentURN) {
		sendMessage(client, new GetChildrenRequest(parentURN));
	}
	
	public void requestViewSensors(IPhysicalClient client, String view, List<PhysicalURN> physicalURNs) {
		sendMessage(client, new ViewSensorsRequest(view, physicalURNs));
	}
	
	public void requestNodeSystems(IPhysicalClient client, PhysicalURN physicalURN) {
		sendMessage(client, new NodeSystemsRequest(physicalURN));
	}
	
	public void requestAttach(IPhysicalClient client) {
		sendMessage(client, new AttachRequest());
	}
	
	public void requestDetach(IPhysicalClient client) {
		sendMessage(client, new DetachRequest());
	}
	
	/**
	 * Implementation of IMessageListener that dispatches messages to an
	 * IPhysicalClient.
	 */
	public class Receiver extends MessageListenerBase {
		
		/**
		 * Handle to callback object for messages from the server to the
		 * client.
		 */
		IPhysicalClient client;
		
		public Receiver(IPhysicalClient client) {
			this.client = client;
		}
		
		public void onClose() throws Exception {
			client.informDisconnect();
		}
		
		public void cfgmngrGetChildrenReply(GetChildrenReply msg) {
			client.replyGetChildren(msg.getResult(), msg.getParentURN(), msg.getChildrenURNs());
		}
		
		public void cfgmngrViewSensorInform(ViewSensorInform msg) {
			client.informViewSensor(msg.getView(), msg.getPhysicalURN(), msg.getSensorURN());
		}
		public void cfgmngrViewSensorsReply(ViewSensorsReply msg) {
			client.replyViewSensors(msg.getResult(), msg.getView(), msg.getNumber());
		}
		
		public void cfgmngrNodeSystemsReply(NodeSystemsReply msg) {
			client.replyNodeSystems(msg.getResult(), msg.getPhysicalURN(), msg.getSystemURNs());
		}
		
		public void cfgmngrAttachReply(AttachReply msg) {
			client.replyAttach(msg.getResult());
		}
		
		public void cfgmngrDetachReply(DetachReply msg) {
			client.replyDetach(msg.getResult());
		}
		
		public void cfgmngrViewEventInform(ViewEventInform msg) {
			client.informViewEvent(msg.getView(), msg.getEvent());
		}
	}

}
